#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "shmem.h"

// 与主程序相同的定义
#define MAX_NODE 128
#define STD_NODE_LEN sizeof(struct std_node)

// 设备类型定义
#define DEV_TYPE_STM32 0
#define DEV_TYPE_MODBUS 1

// 与主程序相同的结构定义
union val_t {
    int b_val;   // bool类型存储空间
    int i_val;   // 整形值存储空间
    float f_val; // 浮点值存储空间
};

struct std_node {
    int key;             // 唯一键值
    int type;            // 数据点类型
    int dev_type;        // 数据点属于哪个设备
    union val_t old_val; // 变化上报后需要更新旧值
    union val_t new_val; // 从共享内存取出最新数据，放到new_val中
    int ret;             // 默认为-1，采集成功后设置为0，采集失败再置-1
};

int main() {
    // 创建共享内存
    struct shm_param para;
    int ret = shm_init(&para, "shm_test", 4096);
    if (ret < 0) {
        fprintf(stderr, "Failed to initialize shared memory\n");
        return EXIT_FAILURE;
    }

    // 获取共享内存地址
    void *node_p = shm_getaddr(&para);
    if (node_p == NULL) {
        fprintf(stderr, "Failed to get shared memory address\n");
        return EXIT_FAILURE;
    }

    // 设置共享内存指针
    int *total = (int *)node_p;
    struct std_node *nodes = (struct std_node *)((char *)node_p + sizeof(int));
    
    printf("Connected to shared memory. Total nodes: %d\n", *total);

    // 主菜单
    while (1) {
        printf("\n===== Shared Memory Editor =====\n");
        printf("1. List all nodes\n");
        printf("2. Modify node value\n");
        printf("3. Toggle node status (ret)\n");
        printf("4. Add random noise to all values\n");
        printf("5. Exit\n");
        printf("Enter your choice: ");
        
        int choice;
        scanf("%d", &choice);
        
        switch (choice) {
            case 1: // 列出所有节点
                printf("\n%-4s %-8s %-8s %-10s %-8s %s\n", 
                       "ID", "Key", "Type", "DevType", "Status", "Value");
                printf("------------------------------------------------\n");
                
                for (int i = 0; i < *total; i++) {
                    printf("%-4d %-8d %-8d %-10s %-8s ",
                           i,
                           nodes[i].key,
                           nodes[i].type,
                           nodes[i].dev_type == DEV_TYPE_STM32 ? "STM32" : "Modbus",
                           nodes[i].ret == 0 ? "OK" : "ERROR");
                    
                    if (nodes[i].ret == 0) {
                        switch (nodes[i].type) {
                            case 0: // bool
                                printf("%d (bool)", nodes[i].new_val.b_val);
                                break;
                            case 1: // int
                                printf("%d (int)", nodes[i].new_val.i_val);
                                break;
                            case 2: // float
                                printf("%.2f (float)", nodes[i].new_val.f_val);
                                break;
                            default:
                                printf("UNKNOWN");
                        }
                    } else {
                        printf("N/A (error)");
                    }
                    printf("\n");
                }
                break;
                
            case 2: { // 修改节点值
                int id;
                printf("Enter node ID to modify (0-%d): ", *total - 1);
                scanf("%d", &id);
                
                if (id < 0 || id >= *total) {
                    printf("Invalid node ID\n");
                    break;
                }
                
                // 显示当前值
                printf("Current value: ");
                if (nodes[id].ret == 0) {
                    switch (nodes[id].type) {
                        case 0:
                            printf("%d (bool)\n", nodes[id].new_val.b_val);
                            break;
                        case 1:
                            printf("%d (int)\n", nodes[id].new_val.i_val);
                            break;
                        case 2:
                            printf("%.2f (float)\n", nodes[id].new_val.f_val);
                            break;
                    }
                } else {
                    printf("N/A (status error)\n");
                }
                
                // 获取新值
                printf("Enter new value: ");
                switch (nodes[id].type) {
                    case 0: // bool
                        scanf("%d", &nodes[id].new_val.b_val);
                        break;
                    case 1: // int
                        scanf("%d", &nodes[id].new_val.i_val);
                        break;
                    case 2: // float
                        scanf("%f", &nodes[id].new_val.f_val);
                        break;
                }
                
                // 确保状态为正常
                nodes[id].ret = 0;
                
                printf("Node %d updated successfully\n", id);
                break;
            }
                
            case 3: { // 切换节点状态
                int id;
                printf("Enter node ID to toggle status (0-%d): ", *total - 1);
                scanf("%d", &id);
                
                if (id < 0 || id >= *total) {
                    printf("Invalid node ID\n");
                    break;
                }
                
                nodes[id].ret = (nodes[id].ret == 0) ? -1 : 0;
                printf("Node %d status set to %s\n", id, nodes[id].ret == 0 ? "OK" : "ERROR");
                break;
            }
                
            case 4: { // 为所有节点添加随机噪声
                printf("Adding random noise to all node values...\n");
                for (int i = 0; i < *total; i++) {
                    if (nodes[i].ret == 0) { // 只修改正常状态的节点
                        switch (nodes[i].type) {
                            case 0: // bool - 随机翻转
                                nodes[i].new_val.b_val = !nodes[i].new_val.b_val;
                                break;
                            case 1: // int - 增加/减少随机值
                                nodes[i].new_val.i_val += (rand() % 10) - 5; // -5 到 +5
                                break;
                            case 2: // float - 增加/减少随机值
                                nodes[i].new_val.f_val += ((float)rand() / RAND_MAX) * 2.0 - 1.0; // -1.0 到 +1.0
                                break;
                        }
                    }
                }
                printf("Random noise added to all nodes\n");
                break;
            }
                
            case 5: // 退出
                printf("Exiting...\n");
                shm_del(&para);
                return EXIT_SUCCESS;
                
            default:
                printf("Invalid choice. Please try again.\n");
        }
        
        // 添加延迟，让用户看到结果
        sleep(1);
    }
    
    return EXIT_SUCCESS;
}